﻿using System;
using System.Collections.Generic;
using System.Data;
using l1cs.server.model;
using MySql.Data.MySqlClient;
using l1cs.server.model.Instance;
using l1cs.server.utils;

namespace l1cs.server.datatables
{
    class ClanTable
    {
        private static Logger _log = Logger.getLogger( typeof( ClanTable ).FullName );

        private Dictionary<int, L1Clan> _clans = new Dictionary<int, L1Clan>();

        private static ClanTable _instance;

        public static ClanTable getInstance()
        {
            if ( _instance == null )
            {
                _instance = new ClanTable();
            }
            return _instance;
        }

        private ClanTable()
        {/*TTOK*/
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                String sqlstr = "SELECT * FROM clan_data ORDER BY clan_id";
                foreach ( DataRow item in wrapper.GetDataTable( sqlstr ).Rows )
                {
                    L1Clan clan = new L1Clan();
                    int clan_id = SqlUtils.toInt( item["clan_id"] );
                    clan.setClanId( clan_id );
                    clan.setClanName( Convert.ToString( item["clan_name"] ) );
                    clan.setLeaderId( SqlUtils.toInt( item["leader_id"] ) );
                    clan.setLeaderName( Convert.ToString( item["leader_name"] ) );
                    clan.setCastleId( SqlUtils.toInt( item["hascastle"] ) );
                    clan.setHouseId( SqlUtils.toInt( item["hashouse"] ) );

                    L1World.getInstance().storeClan( clan );
                    _clans[clan_id] = clan;
                }
                L1Clan[] AllClan = L1World.getInstance().getAllClans();
                foreach ( L1Clan clan in AllClan )
                {
                    sqlstr = "SELECT char_name FROM characters WHERE ClanID = ?1";
                    MySqlCommand cmd = new MySqlCommand( sqlstr );
                    cmd.Parameters.Add( "?1", MySqlDbType.Int32 ).Value = clan.getClanId();
                    foreach ( DataRow item in wrapper.GetDataTable( cmd ).Rows )
                    {
                        clan.addMemberName( item["char_name"] as String );
                    }
                }
                // クラン倉庫のロード
                foreach ( L1Clan clan in AllClan )
                {
                    clan.getDwarfForClanInventory().loadItems();
                }
            }
        }

        /// <summary>
        /// 血盟を作成する。
        /// </summary>
        /// <param name="player">血盟主</param>
        /// <param name="clan_name">血盟名</param>
        /// <returns>血盟クラス</returns>
        public L1Clan createClan( L1PcInstance player, String clan_name )
        {/*TTOK*/
            foreach ( L1Clan oldClans in L1World.getInstance().getAllClans() )
            {
                if ( string.Compare( oldClans.getClanName(), clan_name, true ) == 0 )
                {
                    return null;
                }
            }
            L1Clan clan = new L1Clan();
            clan.setClanId( IdFactory.getInstance().nextId() );
            clan.setClanName( clan_name );
            clan.setLeaderId( player.getId() );
            clan.setLeaderName( player.getName() );
            clan.setCastleId( 0 );
            clan.setHouseId( 0 );

            String sqlstr = @"INSERT INTO clan_data SET 
                                clan_id     = ?1, 
                                clan_name   = ?2, 
                                leader_id   = ?3, 
                                leader_name = ?4, 
                                hascastle   = ?5, 
                                hashouse    = ?6";
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                MySqlCommand cmd = new MySqlCommand( sqlstr );
                cmd.Parameters.Add( "?1", MySqlDbType.Int32 ).Value = clan.getClanId();
                cmd.Parameters.Add( "?2", MySqlDbType.String ).Value = clan.getClanName();
                cmd.Parameters.Add( "?3", MySqlDbType.Int32 ).Value = clan.getLeaderId();
                cmd.Parameters.Add( "?4", MySqlDbType.String ).Value = clan.getLeaderName();
                cmd.Parameters.Add( "?5", MySqlDbType.Int32 ).Value = clan.getCastleId();
                cmd.Parameters.Add( "?6", MySqlDbType.Int32 ).Value = clan.getHouseId();
                wrapper.ExecNonQuery( cmd );
            }
            L1World.getInstance().storeClan( clan );
            _clans[clan.getClanId()] = clan;

            player.setClanid( clan.getClanId() );
            player.setClanname( clan.getClanName() );
            player.setClanRank( L1Clan.CLAN_RANK_PRINCE );
            clan.addMemberName( player.getName() );
            // DBにキャラクター情報を書き込む
            player.save();

            return clan;
        }

        /// <summary>
        /// 血盟のアジトを変更する。
        /// </summary>
        /// <param name="clan"></param>
        public void updateClan( L1Clan clan )
        {/*TTOK*/
            String sqlstr = @"UPDATE clan_data SET 
                                clan_id         = ?1, 
                                leader_id       = ?2, 
                                leader_name     = ?3, 
                                hascastle       = ?4, 
                                hashouse        = ?5 
                                WHERE clan_name = ?6";
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                MySqlCommand cmd = new MySqlCommand( sqlstr );
                cmd.Parameters.Add( "?1", MySqlDbType.Int32 ).Value = clan.getClanId();
                cmd.Parameters.Add( "?2", MySqlDbType.Int32 ).Value = clan.getLeaderId();
                cmd.Parameters.Add( "?3", MySqlDbType.String ).Value = clan.getLeaderName();
                cmd.Parameters.Add( "?4", MySqlDbType.Int32 ).Value = clan.getCastleId();
                cmd.Parameters.Add( "?5", MySqlDbType.Int32 ).Value = clan.getHouseId();
                cmd.Parameters.Add( "?6", MySqlDbType.String ).Value = clan.getClanName();
                wrapper.ExecNonQuery( cmd );
            }
        }

        /// <summary>
        /// 血盟解散
        /// </summary>
        /// <param name="clan_name">血盟名</param>
        public void deleteClan( String clan_name )
        {/*TTOK*/
            L1Clan clan = L1World.getInstance().getClan( clan_name );
            if ( clan == null )
            {
                return;
            }
            String sqlstr = "DELETE FROM clan_data WHERE clan_name=?1";
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                MySqlCommand cmd = new MySqlCommand( sqlstr );
                cmd.Parameters.Add( "?1", MySqlDbType.String ).Value = clan_name;
                wrapper.ExecNonQuery( cmd );
            }
            clan.getDwarfForClanInventory().clearItems();
            clan.getDwarfForClanInventory().deleteAllItems();

            L1World.getInstance().removeClan( clan );
            _clans.Remove( clan.getClanId() );
        }

        public L1Clan getTemplate( int clan_id )
        {/*TTOK*/
            L1Clan ret;
            _clans.TryGetValue( clan_id, out ret );
            return ret;
        }
    }
}
